////////////////////////////////////////////////////////////////////////////////
//
//  FLYING KIWI BV
//  Copyright 2010 Flying Kiwi BV
//  All Rights Reserved.
//
//  NOTICE: Flying Kiwi permits you to use, modify, and distribute this file
//  in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////
package plantool.modules.workplaces.display {
	import flash.display.GradientType;
	import flash.events.Event;
	import flash.geom.Matrix;
	
	import caurina.transitions.Tweener;
	
	import kiwi.components.DragObject;
	import kiwi.display.DisplayObject;
	
	import plantool.modules.users.data.User;
	import plantool.modules.users.display.IUserHour;

	//--------------------------------------------------------------------------
	//  Imports
	//--------------------------------------------------------------------------
	//--------------------------------------------------------------------------
	//  [Metadata (Events, Style, Effects etc)]
	//--------------------------------------------------------------------------
	
	//--------------------------------------------------------------------------
	//  Class declaration
	//--------------------------------------------------------------------------
	public class WorkplaceDay extends WorkplaceDisplayObject implements IWorkplaceDay {
		//--------------------------------------------------------------------------
		//Class constants
		//--------------------------------------------------------------------------
		[Event(name="change", type="flash.events.Event")]
		
		//--------------------------------------------------------------------------
		//Class variables
		//--------------------------------------------------------------------------
		private var _date:Date				= null;
		private var _height:Number			= 20;
		private var _userIds:Array							= new Array();
		private var _userHours:Vector.<WorkplaceUserHour>	= new Vector.<WorkplaceUserHour>();
		private var _orderrowIds:Array						= new Array();
		private var _orderrows:Vector.<IWorkplaceOrderrow>	= new Vector.<IWorkplaceOrderrow>();
		
		//--------------------------------------------------------------------------
		//Class properties
		//--------------------------------------------------------------------------
		public function get date():Date {
			return _date;
		}
		public function set date(value:Date):void {
			_date = new Date(value);
		}
		
		public override function get width():Number {
			return 162;
		}
		
		public override function get height():Number {
			return _height;
		}
		public override function set height(value:Number):void {
			if (_height != value) {
				_height = value;
				draw();
			}
		}
		
		//--------------------------------------------------------------------------
		//Constructor and Destructor
		//--------------------------------------------------------------------------
		public function WorkplaceDay() {
			super();
		}
		
		//--------------------------------------------------------------------------
		//Class methods
		//--------------------------------------------------------------------------
		private function calculateHeight():void {
			//calculate new height
			_height = Math.max(20, (_userIds.length * 10) + (_orderrowIds.length * 15));
		}
		
		private function onChange_hour(e:Event):void {
			//get hour
			var idx:uint = _userHours.indexOf(e.currentTarget as WorkplaceUserHour);
			var hour:WorkplaceUserHour = _userHours[idx];
			
			//remove event
			hour.removeEventListener(Event.CHANGE	, onChange_hour);
			
			//remove hour
			_userHours.splice(idx, 1);
			
			//dispatch change event
			positionHours();
			positionOrders();
			dispatchEvent(new Event(Event.CHANGE));
			
			//invalidate
			invalidate();
		}
		
		private function onChange_orderRow(e:Event):void {
			//get hour
			var idx:uint = _orderrows.indexOf(e.currentTarget as WorkplaceOrderrow);
			var row:WorkplaceOrderrow = _orderrows[idx];
			
			//remove event
			row.removeEventListener(Event.CHANGE	, onChange_orderRow);
			
			//remove hour
			_orderrows.splice(idx, 1);
			
			//dispatch change event
			positionHours();
			positionOrders();
			dispatchEvent(new Event(Event.CHANGE));
			
			//invalidate
			invalidate();
		}
		
		private function positionHours():void {
			_userIds = new Array();
			
			for (var i:uint = 0; i < _userHours.length; i++) {
				//get the hour
				var hour:IWorkplaceUserHour = _userHours[i];
				
				//check if user already has a row
				var idx:int = _userIds.indexOf(hour.user.id);
				if (idx == -1) {
					idx = _userIds.push(hour.user.id) -1;
				}
				
				//position hour
				(hour as DisplayObject).x = (hour.date.hours - dateApi.dayStartHour) * 20;
				(hour as DisplayObject).y = idx * 10;
			}
		}
		
		private function positionOrders():void {
			_orderrowIds = new Array();
			
			var sortFunc:Function = function(itemA:IWorkplaceOrderrow, itemB:IWorkplaceOrderrow):Number {
				if (itemA.orderData.id < itemB.orderData.id) return -1;
				else if (itemA.orderData.id > itemB.orderData.id) return 1;
				return 0;
				
			}
			_orderrows.sort(sortFunc);
			
			for (var i:uint = 0; i < _orderrows.length; i++) {
				//get the hour
				var order:IWorkplaceOrderrow = _orderrows[i];
				
				//check if user already has a row
				var idx:int = _orderrowIds.indexOf(order.orderData.orderrow_id);
				if (idx == -1) {
					idx = _orderrowIds.push(order.orderData.orderrow_id) - 1;
				}
				
				//position hour
				(order as DisplayObject).y = (_userIds.length * 10) + (idx * 15);
			}
		}
		
		protected override function init():void {
			invalidate();
		}
		
		public override function draw():void {
			//position hours
			positionHours();
			
			//position Orders
			positionOrders();
			
			//create button graphics
			graphics.clear();
			graphics.beginFill(0xCCCCCC, 0.35);
			graphics.drawRect(0, 0, 160, height);
			graphics.endFill();
			
			var myMatrix:Matrix = new Matrix();
			myMatrix.createGradientBox(160, height, Math.PI / 4, 0, 0);
			var colors:Array = [0xFFFFFF, 0xFFFFFF];
			var alphas:Array = [0.4, 0.6];
			var ratios:Array = [0, 255];
			
			graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, myMatrix);
			graphics.drawRect(0, 0, 160, height);
			graphics.endFill();
			
			graphics.beginFill(0);
			graphics.drawRect(160, 0, 2, height);
			graphics.endFill();
		}
		
		public function dragObjectOver(target:DragObject):void {
			Tweener.addTween(this, { _autoAlpha: 0.25, time: .25 });
		}
		
		public function dragObjectOut(target:DragObject):void {
			Tweener.addTween(this, { _autoAlpha: 1, time: .25 });
		}
		
		public function addHour(hour:IWorkplaceUserHour):void {
			//add hour
			_userHours.push(hour);
			(hour as WorkplaceUserHour).addEventListener(Event.CHANGE		, onChange_hour);
			
			//add hour
			addChild(hour as DisplayObject);
			
			//position hours
			positionHours();
			
			//position Orders
			positionOrders();
			
			//calculate height
			calculateHeight();
			
			//dispatch change event
			dispatchEvent(new Event(Event.CHANGE));
			
			//invalidate
			invalidate();
		}
		
		public function addPlannedOrder(order:IWorkplaceOrderrow):void {
			//add new order
			_orderrows.push(order);
			
			//listen to change
			(order as WorkplaceOrderrow).addEventListener(Event.CHANGE		, onChange_orderRow);
			
			//add hour
			addChild(order as DisplayObject);
			
			//position hours
			positionHours();
			
			//position Orders
			positionOrders();
			
			//calculate height
			calculateHeight();
			
			//dispatch change event
			dispatchEvent(new Event(Event.CHANGE));
			
			//invalidate
			invalidate();
		}
		
		public function getCalculatedHeight():Number {
			return Math.max(20, (_userIds.length * 10) + (_orderrowIds.length * 15));
		}
	}
}